"""Модуль со вспомогательными функциями генерации."""
import itertools
import json
import os
import random
import string

import cv2
import requests
from PIL import Image, ImageDraw, ImageFilter, ImageFont

from .utils import sp_transliterate


def process_generate_signature(user_id, data):
    """Генерация подписи."""
    text = sp_transliterate(str(data.capitalize()))
    txt = Image.new("RGBA", (1900, 600), (255, 255, 255, 0))
    go_txt = ImageDraw.Draw(txt)
    fnt1 = ImageFont.truetype(f"./fonts/1.ttf", size=270)
    go_txt.text(xy=(200, 50), text=f"{text}", font=fnt1, fill="#000000")
    fnt2 = ImageFont.truetype(f"./fonts/2.ttf", size=190)
    go_txt.text(xy=(800, 50), text=f"{text}", font=fnt2, fill="#000000", stroke_width=1)
    fnt3 = ImageFont.truetype(f"./fonts/3.ttf", size=200)
    go_txt.text(
        xy=(1400, 50), text=f"{text}", font=fnt3, fill="#000000", stroke_width=1
    )
    fnt4 = ImageFont.truetype(f"./fonts/4.ttf", size=100)
    go_txt.text(
        xy=(200, 400), text=f"{text}", font=fnt4, fill="#000000", stroke_width=1
    )
    fnt5 = ImageFont.truetype(f"./fonts/5.ttf", size=150)
    go_txt.text(
        xy=(800, 400), text=f"{text}", font=fnt5, fill="#000000", stroke_width=1
    )
    fnt6 = ImageFont.truetype(f"./fonts/6.ttf", size=80)
    go_txt.text(xy=(1400, 400), text=f"{text}", font=fnt6, fill="#000000")
    fnt66 = ImageFont.truetype(f"./fonts/66.ttf", size=80)
    go_txt.text(xy=(1430, 440), text=f"k", font=fnt66, fill="#000000")
    txt_blur = txt.filter(ImageFilter.GaussianBlur(radius=1))
    holst = Image.new("RGBA", (1900, 600), (255, 255, 255, 255))
    choose_signature = Image.alpha_composite(holst, txt_blur)
    choose_signature.save(f"./files/es/photo_usr/{user_id}_choose_signature.png")


def process_passport_photo(user_id):
    """Проверка фотографии на соответствие и её обработка."""
    try:
        # Загрузите классификатор изображений и распознавания лиц
        img = cv2.imread(f"./files/es/photo_usr/{user_id}.png", cv2.IMREAD_UNCHANGED)
        face_cascade = cv2.CascadeClassifier(
            f"./data/haarcascade_frontalface_default.xml"
        )

        # Обнаружение лиц на изображении
        faces = face_cascade.detectMultiScale(img, 1.2, 5)

        # Если лица обнаружены, обрежьте и измените размер изображения
        if len(faces) != 0:
            (x, y, w, h) = faces[0]
            h_top = int(h * 0.4)
            h_bottom = int(h * 0.3)
            w_left = int(w * 0.2)
            w_right = int(w * 0.2)
            x_left = max(0, x - w_left)
            x_right = min(img.shape[1], x + w + w_right)
            w_new = x_right - x_left
            y_top = max(0, y - h_top)
            y_bottom = min(img.shape[0], y + h + h_bottom)
            h_new = y_bottom - y_top

            cropped_img = img[y_top : y_top + h_new, x_left : x_left + w_new]
            cropped_img_pil = Image.fromarray(
                cv2.cvtColor(cropped_img, cv2.COLOR_BGRA2RGBA)
            )

            # Измените размер изображения пропорционально ширине 544 пикселей.
            target_width = 544
            width_ratio = target_width / cropped_img_pil.width
            new_width = target_width
            new_height = int(cropped_img_pil.height * width_ratio)
            resized_width = cropped_img_pil.resize(
                (new_width, new_height), Image.ANTIALIAS
            )

            # Измените размер изображения пропорционально высоте 660 пикселей.
            target_height = 660
            height_ratio = target_height / resized_width.height
            new_height = target_height
            new_width = int(resized_width.width * height_ratio)
            resized_height = resized_width.resize(
                (new_width, new_height), Image.ANTIALIAS
            )

            # Обрежьте изображение по центру, чтобы получить ширину 544 пикселя.
            left = (resized_height.width - target_width) / 2
            top = 0
            right = (resized_height.width + target_width) / 2
            bottom = new_height
            cropped_resized = resized_height.crop((left, top, right, bottom))

            # Преобразуйте изображение и сохраните альфа-канал.
            grayscale_img = cropped_resized.convert("RGBA")
            grayscale_img.putalpha(cropped_resized.getchannel("A"))

            # Сохраните обработанное изображение с альфа-каналом
            image = Image.new("RGBA", grayscale_img.size, (255, 255, 255, 0))
            image = Image.alpha_composite(image, grayscale_img)
            image.save(f"./files/es/photo_usr/{user_id}_w.png")
            os.remove(f"./files/es/photo_usr/{user_id}.png")
        else:
            print(f"No faces found in image for user_id {user_id}")
    except Exception as e:
        print(f"Error processing passport photo for user_id {user_id}: {str(e)}")


def process_id_photo(user_id):
    """Проверка фотографии на соответствие и её обработка."""
    try:
        # Загрузите классификатор изображений и распознавания лиц
        img = cv2.imread(f"./files/es/photo_usr/{user_id}.png", cv2.IMREAD_UNCHANGED)
        face_cascade = cv2.CascadeClassifier(
            f"./data/haarcascade_frontalface_default.xml"
        )

        # Обнаружение лиц на изображении
        faces = face_cascade.detectMultiScale(img, 1.2, 5)

        # Если лица обнаружены, обрежьте и измените размер изображения
        if len(faces) != 0:
            (x, y, w, h) = faces[0]
            h_top = int(h * 0.4)
            h_bottom = int(h * 0.3)
            w_left = int(w * 0.2)
            w_right = int(w * 0.2)
            x_left = max(0, x - w_left)
            x_right = min(img.shape[1], x + w + w_right)
            w_new = x_right - x_left
            y_top = max(0, y - h_top)
            y_bottom = min(img.shape[0], y + h + h_bottom)
            h_new = y_bottom - y_top

            cropped_img = img[y_top : y_top + h_new, x_left : x_left + w_new]
            cropped_img_pil = Image.fromarray(
                cv2.cvtColor(cropped_img, cv2.COLOR_BGRA2RGBA)
            )

            # Измените размер изображения пропорционально ширине 544 пикселей.
            target_width = 1300
            width_ratio = target_width / cropped_img_pil.width
            new_width = target_width
            new_height = int(cropped_img_pil.height * width_ratio)
            resized_width = cropped_img_pil.resize(
                (new_width, new_height), Image.ANTIALIAS
            )

            # Измените размер изображения пропорционально высоте 660 пикселей.
            target_height = 1750
            height_ratio = target_height / resized_width.height
            new_height = target_height
            new_width = int(resized_width.width * height_ratio)
            resized_height = resized_width.resize(
                (new_width, new_height), Image.ANTIALIAS
            )

            # Обрежьте изображение по центру, чтобы получить ширину 544 пикселя.
            left = (resized_height.width - target_width) / 2
            top = 0
            right = (resized_height.width + target_width) / 2
            bottom = new_height
            cropped_resized = resized_height.crop((left, top, right, bottom))

            # Преобразуйте изображение и сохраните альфа-канал.
            grayscale_img = cropped_resized.convert("RGBA")
            grayscale_img.putalpha(cropped_resized.getchannel("A"))

            # Сохраните обработанное изображение с альфа-каналом
            image = Image.new("RGBA", grayscale_img.size, (255, 255, 255, 0))
            image = Image.alpha_composite(image, grayscale_img)
            image.save(f"./files/es/photo_usr/{user_id}_w.png")
            os.remove(f"./files/es/photo_usr/{user_id}.png")
        else:
            print(f"No faces found in image for user_id {user_id}")
    except Exception as e:
        print(f"Error processing passport photo for user_id {user_id}: {str(e)}")


def generate_number_password(flag: bool = False, count: int = 6):
    """Генерация номера паспорта."""
    letters = string.ascii_uppercase
    digits = string.digits
    prefix = "".join(random.choice(letters) for _ in range(3))
    suffix = "".join(random.choice(digits) for _ in range(count))
    if flag:
        return suffix
    result = prefix + suffix
    return result


def generate_number_doc():
    """Генерация номера документа."""
    letters = string.ascii_uppercase
    digits = string.digits
    prefix = "".join(random.choice(letters) for _ in range(2))
    suffix = "".join(random.choice(digits) for _ in range(6))

    result = "B" + prefix + suffix
    return result


def generate_EQUIPO_number():
    """Генерация EQUIPO номера."""
    letters = string.ascii_uppercase
    digits = string.digits
    digits_first = "".join(random.choice(digits) for _ in range(5))
    letters_first = "".join(random.choice(letters) for _ in range(1))
    digits_two = "".join(random.choice(digits) for _ in range(1))
    letters_two = "".join(random.choice(letters) for _ in range(1))
    digits_three = "".join(random.choice(digits) for _ in range(1))

    result = digits_first + letters_first + digits_two + letters_two + digits_three
    return result


def generate_dni_number():
    """Генерация DNI номера."""
    letters = string.ascii_uppercase
    digits = string.digits
    digits_first = "".join(random.choice(digits) for _ in range(8))
    while True:
        letters_first = "".join(random.choice(letters) for _ in range(1))
        if letters_first != "o" or letters_first != "O":
            break

    result = digits_first + letters_first
    return result


def art_converter(file_path: str, user_id: str, symbols: list):
    """Функция рендеринга изображения в символы."""
    img = Image.open(file_path).convert("RGBA")
    txt = Image.new("RGBA", img.size, (255, 255, 255, 0))
    go_txt = ImageDraw.Draw(txt)
    size_font = 22
    font = ImageFont.truetype(f"./fonts/es_passport2.ttf", size_font)
    # Определение символов Ascii для использования
    symbols = [x for x in symbols if x != " "]
    ascii_chars = itertools.cycle(symbols)

    # Определение ширины и высоты изображения
    width, height = img.size

    # Определение шага для выборки пикселей
    step = int(size_font * 0.6)

    # Итерация по строкам изображения
    for y in range(0, height, step + step // 2):
        for x in range(0, width, step):
            # Получение RGB-значения пикселя
            r, g, b, _ = img.getpixel((x, y))
            # Рисуем вместо пикселя, символ в тех же цветах
            go_txt.text(
                xy=(x, y),
                text=next(ascii_chars),
                font=font,
                fill=(r, g, b, 235),
                stroke_width=1,
                anchor="lm",
            )

    txt.save(f"./files/es/photo_usr/{user_id}_render.png")


def generate_name(code_country: str) -> str:
    """Генератор случайных имён и фамилий по коду страны."""
    result = ""
    # запрос мужского имени
    request_m_name = requests.get(
        f"https://api.parser.name/?api_key=0edb934eee6496e5fc6113fc8320f4a1&endpoint=generate"
        f"&gender=m"
        f"&country_code={code_country}"
    )
    res_m = json.loads(request_m_name.text)
    for data in res_m["data"]:
        for key, val in data.items():
            if key == "name":
                name = " ".join(data[key]["firstname"]["name_ascii"].split("-"))
                surname = " ".join(data[key]["lastname"]["name_ascii"].split("-"))
                result += f"{surname.upper()} {name.upper()} / "

    # запрос женского имени
    request_f_name = requests.get(
        f"https://api.parser.name/?api_key=0edb934eee6496e5fc6113fc8320f4a1&endpoint=generate"
        f"&gender=f"
        f"&country_code={code_country}"
    )
    res_f = json.loads(request_f_name.text)
    for data in res_f["data"]:
        for key, val in data.items():
            if key == "name":
                name = " ".join(data[key]["firstname"]["name_ascii"].split("-"))
                surname = " ".join(data[key]["lastname"]["name_ascii"].split("-"))
                result += f"{surname.upper()} {name.upper()}"

    return result
